require 'model'

class AccountTreeView < Gtk::VBox
  def initialize(model)
    super()
    @model = model
    @store = Gtk::TreeStore.new(String)
    setup_child_accounts(@model.root_account, nil)
    @view = Gtk::TreeView.new(@store)
    @view.append_column(
      Gtk::TreeViewColumn.new("Accounts", Gtk::CellRendererText.new, :text => 0)
    )
    self.add(@view)
    
    @select_account = proc {|x| puts "selected account #{x}" }
    @view.signal_connect("row-activated") do |view, path, column|
      if iter = view.model.get_iter(path)
        @select_account.call(iter[0])
      end
    end
  end
  
  def on_select_account(&block)
    @select_account = block
  end
  
  def setup_child_accounts(account, parent)
    @model.find_subaccounts(account).each do |acct|
      this_node = @store.append(parent)
      this_node[0] = acct.account_name
      setup_child_accounts(acct, this_node)
    end
  end
end

class TransactionListView < Gtk::VBox  
  def initialize(model, account)
    super()
    @model = model
    @account = account
    @view = Gtk::VBox.new

    draw_bg = false
    @model.find_transactions(account).sort{|x,y| x.date <=> y.date}.each do |tx|
      @view.pack_start(TransactionView.new(tx, account, draw_bg), false, false, 0)
      draw_bg = !draw_bg
    end
    add_tx_button = Gtk::Button.new("Add Transaction")
    add_tx_button.signal_connect("clicked"){|b| add_transaction}
    @view.pack_start(add_tx_button, false, false, 0)
    
    @header_label = Gtk::Label.new
    @header_label.markup = "Account: <b>#{account.account_name}</b>, Current Balance: <b>#{Util.to_usd(account.current_balance)}</b>"
    self.pack_start(@header_label, false, false, 5)
    @scroller = Gtk::ScrolledWindow.new
    @scroller.add_with_viewport(@view)
    self.pack_start(@scroller, true, true, 0)
  end
  
  def add_transaction
    puts "add transaction button pressed"
  end
end

class TransactionView < Gtk::HBox
  KILL_COLUMN = 0
  DATE_COLUMN = 1
  MEMO_COLUMN = 2
  ACCOUNT_COLUMN = 3
  DEBIT_COLUMN = 4
  CREDIT_COLUMN = 5
  BUTTON_COLUMN = 6
  COLUMN_COUNT = 7
  
  def initialize(tx, account, draw_bg = false)
    super()
    @tx = tx
    @account = account
    
    if(draw_bg)
      # darken background
    end
    build_transaction
  end
  
  def add_row
    puts "row adder button pressed"
  end
  
  def build_transaction
    @table = Gtk::Table.new(1, COLUMN_COUNT)
    self.pack_start(@table, true, true, 0)
    
    kill_button = Gtk::Button.new("x")
    kill_button.signal_connect("clicked"){|b| kill_transaction}
    @table.attach(kill_button, KILL_COLUMN, KILL_COLUMN + 1, 0, 1, nil, nil, 0, 0)
    
    date_entry = Gtk::Entry.new
    date_entry.width_chars = 10
    date_entry.text = @tx.date.to_s
    @table.attach(date_entry, DATE_COLUMN, DATE_COLUMN + 1, 0, 1, nil, nil, 0, 0)
    
    memo_entry = Gtk::Entry.new
    memo_entry.width_chars = 16
    memo_entry.text = "memo"
    @table.attach(memo_entry, MEMO_COLUMN, MEMO_COLUMN + 1, 0, 1, nil, nil, 0, 0)
    
    build_entries
    self.show_all
  end

  def build_entries
    fe = get_foreign_entries
    if(1 == fe.length)
      build_row(0, fe[0])
    else
      @table.resize(fe.length, 6)
      fe.each_index do |row_index|
        show_adder = (fe.length - 1) == row_index
        show_deleter = 0 == row_index
        build_row(row_index, fe[row_index], show_adder, show_deleter)
      end
    end
  end
  
  def build_row(row_index, row, show_adder = true, show_deleter = false)
    acct_entry = Gtk::Entry.new
    debit_entry = Gtk::Entry.new
    credit_entry = Gtk::Entry.new

    acct_entry.width_chars = 32
    debit_entry.width_chars = 16
    credit_entry.width_chars = 16

    debit_entry.xalign = 1
    credit_entry.xalign = 1
    @table.attach(acct_entry, ACCOUNT_COLUMN, ACCOUNT_COLUMN + 1, row_index, row_index + 1, nil, nil, 0, 0)
    @table.attach(debit_entry, DEBIT_COLUMN, DEBIT_COLUMN + 1, row_index, row_index + 1, nil, nil, 0, 0)
    @table.attach(credit_entry, CREDIT_COLUMN, CREDIT_COLUMN + 1, row_index, row_index + 1, nil, nil, 0, 0)

    acct_entry.text = row[:account].account_name
    if(row[:tx_type] == :debit)
      debit_entry.text = Util.to_usd(row[:amount])
    else
      credit_entry.text = Util.to_usd(row[:amount])
    end
    
    if(show_adder)
      adder_button = Gtk::Button.new("+")
      adder_button.signal_connect("clicked"){|b| add_row}
      @table.attach(adder_button, BUTTON_COLUMN, BUTTON_COLUMN + 1, row_index, row_index + 1, nil, nil, 0, 0)
    end
    if(show_deleter)
      deleter_button = Gtk::Button.new("-")
      deleter_button.signal_connect("clicked"){|b| kill_row}
      @table.attach(deleter_button, BUTTON_COLUMN, BUTTON_COLUMN + 1, row_index, row_index + 1, nil, nil, 0, 0)
    end
  end

  def get_account_entries(entries)
    entries.select{|e| e[:account] == @account }
  end

  def get_foreign_entries
    @tx.entries.select{|e| e[:account] != @account }
  end
  
  def kill_row
    puts "kill row button pressed"
  end

  def kill_transaction
    puts "kill transaction button pressed"
  end
end

class AccountPage < Gtk::VBox
  def initialize(model, prefs)
    super()
    @model = model
    @prefs = prefs
    #@toolbar = build_toolbar
    #self.pack_start(@toolbar, false, false, 0)
    @panes = build_panes
    self.pack_start(@panes, true, true, 0)
  end
  
  def build_panes
    account_view = AccountTreeView.new(@model)
    acct_frame = Gtk::Frame.new
    acct_frame.add(account_view)
    
    tx_view = TransactionListView.new(@model, @model[@prefs[:account_page_account]])
    tx_frame = Gtk::Frame.new
    tx_frame.add(tx_view)

    account_view.on_select_account do |acct|
      tx_frame.each{|c| tx_frame.remove(c)}
      tx_view = TransactionListView.new(@model, @model[acct])
      tx_frame.add(tx_view)
      tx_frame.show_all
    end
    
    panes = Gtk::HPaned.new
    panes.position = @prefs[:account_page_list_width]
    panes.pack1(acct_frame, false, true)
    panes.pack2(tx_frame, true, true)
    return panes
  end
end